package com.yami.shop.groupbuy.multishop.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.dto.ProdAndSkuListsDto;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.OfflineHandleEventType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.groupbuy.common.dto.GroupActivityDto;
import com.yami.shop.groupbuy.common.dto.GroupProdAndSkuListDto;
import com.yami.shop.groupbuy.common.enums.ActivityStatusEnum;
import com.yami.shop.groupbuy.common.model.GroupActivity;
import com.yami.shop.groupbuy.common.service.GroupActivityService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.OfflineHandleEventService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.ShopDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import com.yami.shop.common.util.BeanUtil;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/group/activity")
@Tag(name = "商家端拼团活动接口")
public class GroupActivityController {


    private final ProductService productService;
    private final ApplicationEventPublisher eventPublisher;
    private final GroupActivityService groupActivityService;
    private final OfflineHandleEventService offlineHandleEventService;
    private final ShopDetailService shopDetailService;

    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('group:activity:page')")
    @Operation(summary =  "分页获取拼团活动列表")
    public ServerResponseEntity<IPage<GroupActivityDto>> getGroupActivityPage(PageParam<GroupActivityDto> page,@ParameterObject GroupActivityDto groupActivityDto) {
        groupActivityDto.setLang(I18nMessage.getDbLang());
        groupActivityDto.setShopId(SecurityUtils.getShopUser().getShopId());
        return ServerResponseEntity.success(groupActivityService.getGroupActivityPage(page, groupActivityDto));
    }

    @GetMapping("/info/{groupActivityId}")
    @Operation(summary =  "通过id查询拼团活动表")
    @Parameter(name = "groupActivityId", description = "拼团活动id", required = true)
    public ServerResponseEntity<GroupActivity> getById(@PathVariable("groupActivityId") Long groupActivityId) {
        GroupActivity groupActivity = groupActivityService.getGroupActivityInfo(groupActivityId);
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), groupActivity.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(groupActivity);
    }

    @PostMapping
    @PreAuthorize("@pms.hasPermission('group:activity:save')")
    @Operation(summary =  "新增拼团活动表")
    public ServerResponseEntity<Long> save(@RequestBody @Valid GroupActivity groupActivity) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            // 店铺处于违规下线中，不能进行此操作，请联系管理员后重试
            throw new YamiShopBindException("yami.product.shop.offline");
        }
        if (Objects.isNull(groupActivity.getProdId())) {
            // 请选择商品
            throw new YamiShopBindException("yami.score.select.num");
        }
        if (CollUtil.isEmpty(groupActivity.getGroupSkuList())) {
            // sku列表不能为空
            throw new YamiShopBindException("yami.sku.cannot.empty");
        }
        Date now = new Date();
        // 未启用状态
        groupActivity.setStatus(2);
        groupActivity.setShopId(shopId);
        groupActivityService.saveGroupActivity(groupActivity);
        productService.removeProdCacheByProdId(groupActivity.getProdId());
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        // 更新商品信息
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(groupActivity.getGroupActivityId());
    }

    @PutMapping
    @PreAuthorize("@pms.hasPermission('group:activity:update')")
    @Operation(summary =  "修改拼团活动表")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid GroupActivity groupActivity) {
        if (CollUtil.isEmpty(groupActivity.getGroupSkuList())) {
            // sku列表不能为空
            throw new YamiShopBindException("yami.sku.cannot.empty");
        }
        Long prodId = groupActivity.getProdId();
        groupActivity.setShopId(SecurityUtils.getShopUser().getShopId());
        groupActivityService.updateGroupActivity(groupActivity);
        groupActivityService.removeGroupActivityInfoCache(prodId);
        // 更新商品信息
        eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(Boolean.TRUE);
    }

    @PutMapping("/active/{groupActivityId}")
    @Operation(summary =  "通过id启用拼团活动")
    @Parameter(name = "groupActivityId", description = "拼团活动id", required = true)
    public ServerResponseEntity<Boolean> activeGroupActivity(@PathVariable Long groupActivityId) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (groupActivity == null) {
            // 未找到此活动，请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        if (!Objects.equals(shopId, groupActivity.getShopId())) {
            throw new YamiShopBindException("当前拼团活动不属于您的店铺");
        }
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
            throw new YamiShopBindException("店铺处于违规下架状态，不能启用拼团活动");
        }
        int compare = DateUtil.compare(groupActivity.getEndTime(), DateUtil.date());
        if (compare <= 0) {
            // 当前时间已超过活动结束时间，不能启用活动
            throw new YamiShopBindException("yami.activity.now.over.end.time");
        }
        // 启用状态
        GroupActivity newGroupActivity = new GroupActivity();
        newGroupActivity.setGroupActivityId(groupActivityId);
        newGroupActivity.setStatus(1);
        groupActivityService.updateById(newGroupActivity);
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        return ServerResponseEntity.success(true);
    }

    @DeleteMapping("/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:delete')")
    @Operation(summary =  "删除拼团活动表")
    @Parameter(name = "groupActivityId", description = "拼团活动id", required = true)
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long groupActivityId) {
        // 查看活动是否为失效状态或者活动结束
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (Objects.isNull(groupActivity)) {
            // 未找到此活动，请稍后重试
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        boolean canDelete = !(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.EXPIRED.value()) ||
                (groupActivity.getActivityStatus() >= 3 && groupActivity.getActivityStatus() <= 6));
        if (canDelete && groupActivity.getActivityStatus() != 1) {
            // 该活动状态下不能进行删除
            throw new YamiShopBindException("yami.activity.cannot.delete");
        }
        groupActivityService.updateToDelete(groupActivity);
        // 获取该活动下的所有商品
        productService.removeProdCacheByProdId(groupActivity.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success(true);
    }

    /**
     * 获取活动商品的信息及商品下规格信息
     */
    @GetMapping("/getProdAndSkuLists")
    @Operation(summary =  "通过商品id列表获取活动商品的信息及商品下规格信息")
    @Parameter(name = "prodIds", description = "商品id", required = true)
    public ServerResponseEntity<List<GroupProdAndSkuListDto>> getProdAndSkuLists(@RequestParam List<Long> prodIds) {
        List<ProdAndSkuListsDto> prodAndSkuListsDtoList = productService.getProdAndSkuLists(prodIds);
        List<GroupProdAndSkuListDto> groupProdAndSkuLists = BeanUtil.mapAsList(prodAndSkuListsDtoList, GroupProdAndSkuListDto.class);
        return ServerResponseEntity.success(groupProdAndSkuLists);
    }

    @PutMapping("/invalid/{groupActivityId}")
    @PreAuthorize("@pms.hasPermission('group:activity:invalid')")
    @Operation(summary =  "失效进行中的拼团活动")
    @Parameter(name = "groupActivityId", description = "拼团活动id", required = true)
    public ServerResponseEntity<Boolean> invalidActivity(@PathVariable Long groupActivityId) {
        // 查看活动
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        //不是进行中的也不是预热启动的活动
        boolean canInvalid = Objects.isNull(groupActivity) || (!Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value())
                && !(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.NOT_STARTED.value()) && Objects.equals(groupActivity.getStatus(), 1)));
        if (canInvalid) {
            // 失效失败，活动不在进行中无法进行失效操作
            throw new YamiShopBindException("yami.activity.disable");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        if (!Objects.equals(groupActivity.getShopId(), shopId)) {
            // 您无权操作此活动
            throw new YamiShopBindException("yami.activity.no.auth");
        }
        groupActivityService.invalidGroupActivity(groupActivityId);
        eventPublisher.publishEvent(new EsProductUpdateEvent(groupActivity.getProdId(), null, EsOperationType.UPDATE));
        groupActivityService.removeGroupActivityInfoCache(groupActivity.getProdId());
        return ServerResponseEntity.success(true);
    }

    @GetMapping("/getOfflineHandleEventByActivityId/{activityId}")
    @Operation(summary =  "通过活动id获取下线信息")
    @Parameter(name = "activityId", description = "活动id", required = true)
    public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByActivityId(@PathVariable("activityId") Long activityId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.GROUP_BUY.getValue(), activityId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }

    @PostMapping("/auditApply")
    @PreAuthorize("@pms.hasPermission('group:activity:auditApply')")
    @Operation(summary =  "申请审核拼团活动")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        groupActivityService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        return ServerResponseEntity.success();
    }
}
